/*
 * text_body_visualizer.c
 * This file is part of gURL
 *
 * Copyright (C) 2014 - Aleksey Konovalov
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Library General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "text_body_visualizer.h"

#include "body_visualizer.h"
#include "defines.h"
#include <glib/gi18n.h>
#include "gurl_conf.h"
#include "highlighter/highlighter.h"
#include <stdbool.h>
#include "text_edit.h"

struct _TextBodyVisualizer {
    TextEdit parent;
    GtkWidget* pretty_print_btn;
    Session* session;
};

struct _TextBodyVisualizerClass {
    TextEditClass parent;
};

static void text_body_visualizer_interface_init(BodyVisualizerInterface* iface);

G_DEFINE_TYPE_WITH_CODE(TextBodyVisualizer, text_body_visualizer, TEXT_EDIT_TYPE,
                        G_IMPLEMENT_INTERFACE(BODY_VISUALIZER_TYPE,
                                              text_body_visualizer_interface_init))

static void text_body_visualizer_change_session(BodyVisualizer* self,
                                                Session* session) {
    TextBodyVisualizer* tbv = TEXT_BODY_VISUALIZER(self);
    tbv->session = session;
    GtkTextBuffer* tb = text_edit_get_buffer(TEXT_EDIT(tbv));
    if(session) {
        Encoding enc = session_get_response_content_encoding(session);
        if(enc == UNKNOWN_ENCODING)
            enc = enc_ASCII;
        text_edit_set_encoding(TEXT_EDIT(tbv), enc);
        const GString* body = session_get_response_body(session);
        GString* body_converted = decode_string(body->str, body->len, enc);
        if(body_converted) {
            gtk_text_buffer_set_text(tb, body_converted->str,
                                         body_converted->len);
            const gboolean pprint_available = prettyprint_available(
                session_get_response_content_type(session)->str);
            gtk_widget_set_visible(tbv->pretty_print_btn, pprint_available);
            const gboolean prettyprint = pprint_available &&
                gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tbv->pretty_print_btn));
            highlight(tb, body_converted->str, body_converted->len,
                      session_get_response_content_type(session)->str,
                      prettyprint);
            g_string_free(body_converted, TRUE);
        } else
            gtk_text_buffer_set_text(tb, _("[Invalid encoding]"), -1);
    } else {
        gtk_widget_hide(tbv->pretty_print_btn);
        gtk_text_buffer_set_text(tb, "", 0);
    }
}

static void text_body_visualizer_interface_init(BodyVisualizerInterface* iface) {
    iface->change_session = text_body_visualizer_change_session;
    iface->name = _("Text");
}

static const char* const CONF_GROUP = "response view";
static const char* const CONF_PRETTYPRINT_KEY = "prettyprint";

static void on_encoding_changed(GtkWidget* UNUSED(widget),
                                          int encoding, gpointer p) {
    TextBodyVisualizer* tbv = TEXT_BODY_VISUALIZER(p);
    if(tbv->session) {
        session_set_response_content_encoding(tbv->session, encoding);
        text_body_visualizer_change_session(BODY_VISUALIZER(tbv), tbv->session);
    }
}

static void on_switch_pretty_print(GtkWidget* widget, gpointer p) {
    config_set_bool(CONF_GROUP, CONF_PRETTYPRINT_KEY,
                  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
    text_body_visualizer_change_session(BODY_VISUALIZER(p),
                                        TEXT_BODY_VISUALIZER(p)->session);
}

static void text_body_visualizer_init(TextBodyVisualizer* self) {
    self->session = NULL;

    text_edit_set_editable(TEXT_EDIT(self), false);
    g_signal_connect(G_OBJECT(self), "encoding-changed",
                     G_CALLBACK(on_encoding_changed), self);

    self->pretty_print_btn = gtk_check_button_new_with_label(_("Pretty-print"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->pretty_print_btn),
        config_get_bool(CONF_GROUP, CONF_PRETTYPRINT_KEY, TRUE));
    g_signal_connect(self->pretty_print_btn, "toggled",
                     G_CALLBACK(on_switch_pretty_print), self);
    GtkBox* box = text_edit_get_topbox(TEXT_EDIT(self));
    gtk_box_pack_end(box, self->pretty_print_btn, TRUE, TRUE, 30);
}

static void text_body_visualizer_class_init(TextBodyVisualizerClass* klass) {}

GtkWidget* text_body_visualizer_new() {
    return g_object_new(TEXT_BODY_VISUALIZER_TYPE, "orientation",
                        GTK_ORIENTATION_VERTICAL, NULL);
}
